package de.lmu.ifi.pst.uwejsf.framework.process;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

import de.lmu.ifi.pst.uwejsf.framework.AbstractUWEContextFactory;
import de.lmu.ifi.pst.uwejsf.framework.ExpressionHelpers;
import de.lmu.ifi.pst.uwejsf.framework.PersistenceManager;

public abstract class SystemAction extends Action {

	protected Map<String, Object> parameters = new HashMap<String, Object>();

	public SystemAction(ProcessActivityBean activity) {
		super(activity);
	}

	private SystemActionHandler handler;

	public SystemActionHandler getHandler() {
		return handler;
	}

	public void execute() {
		Map<String, Object> scope = new HashMap<String, Object>();
		Map<String, Object> managedBeans = AbstractUWEContextFactory
				.getCurrentInstance().getManagedBeans();
		scope.putAll(managedBeans);
		scope.putAll(activity.getObjectStorage());

		PersistenceManager pm = AbstractUWEContextFactory.getCurrentInstance()
				.getPersistenceManager();

		scope.put("persistenceManager", pm);
		Map<String, Object> result = handler.execute(parameters, scope);
		storeResultValues(result);
	}

	public void setHandler(SystemActionHandler handler) {
		this.handler = handler;
	}

	public void setInputValue(String name, Object value) {
		parameters.put(name, value);
	}

	@Override
	public void populateInputValues(Object bean) {

		if (bean instanceof Map) {
			for (Object o : ((Map<?, ?>) bean).keySet()) {
				parameters.put(o.toString(), ((Map<?, ?>) bean).get(o));
			}
		} else {
			try {

				Map<?, ?> props = BeanUtils.describe(bean);
				for (Object key : props.keySet()) {
					parameters.put((String) key, props.get(key));
				}

			} catch (Exception e) {
				throw new ProcessDataflowException(
						"Couldn't extract bean properties from bean of type "
								+ bean.getClass().toString(), e);
			}
		}
	}

	public abstract void storeResultValues(java.util.Map<String, Object> result);
}
